﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BankingSystem.BLL
{
    public static class HelperBank
    {
        /// <summary>
        /// Получение информации о колличестве зарегестриванных пользователей по критерию FirstName и LastName
        /// </summary>
        public static String InfoAboutUsers(this Bank bank)
        {
            Int32 _firstNames = bank.Clients.Where(i => i.Information.FistName != "").Select(i => i).Count();
            Int32 _secondName = bank.Clients.Where(i => i.Information.LastName != "").Select(i => i).Count();

            return String.Format("найдено в базе {0} FirstName и {1} SecondName", _firstNames, _secondName);
        }

        /// <summary>
        /// Возвращает список зарегестрированных лиц по критерию FirstName
        /// </summary>
        public static List<String> SpisokFirstName(this Bank bank)
        {
            return bank.Clients.Select(i => i.Information.FistName).ToList<String>();
        }


        /// <summary>
        /// Возвращает список зарегестрированных лиц по критерию LastName
        /// </summary>
        public static List<String> SpisokLastName(this Bank bank)
        {
            return bank.Clients.Select(i => i.Information.LastName).ToList<String>();
        }

        /// <summary>
        /// Возвращает число зарегестрированных лиц с заданным именем name
        /// </summary>
        public static Int32 UsersByFirstName(this Bank bank, String name)
        {
            Int32 count = 0;
            var usersByFirstName = bank.Clients.GroupBy(i => i.Information.FistName).Select(i => i).Where(i => i.Key == name).Select(i => i);
            foreach (Client i in usersByFirstName)
            {
                    count++;
            }
            return count;
        }

        /// <summary>
        /// Возвращает общее число денежных средств, хранящихся в банке
        /// </summary>
        public static Double AllCountMoneyByBank(this Bank bank)
        {
            Double money = 0;
            var moneys = from c in bank.Accounts select c.Balance;
            foreach (var i in moneys.ToList<Double>())
            {
                money += i;
            }
            return money;
        }

        /// <summary>
        /// Возвращает усредненное число денежных средств, приходящихся на ожного держателя в банке
        /// </summary>
        public static Double AverageCountMoneyByUser(this Bank bank)
        {
            Double moneys = AllCountMoneyByBank(bank);
            Int32 users = bank.Clients.Select(i => i.ID).ToList<String>().Count();
            return moneys / users;
        }

        /// <summary>
        /// Возвращает пользователей с масимальным счетом в банке
        /// </summary>
        public static List<Client> MaxMoneyByAccount(this Bank bank)
        {
            Double maxMoney = bank.Accounts.Max(i => i.Balance);
            return bank.Accounts.Where(i => i.Balance == maxMoney).Select(i => i.OwnerClient).ToList<Client>();
        }

        /// <summary>
        /// Возвращает первых 2 пользователей с масимальным счетом в банке
        /// </summary>
        public static List<Client> MaxMoneyByAccountIntoTwoUsers(this Bank bank)
        {
            Double maxMoney = bank.Accounts.Max(i => i.Balance);
            return bank.Accounts.Where(i => i.Balance == maxMoney).Select(i => i.OwnerClient).Take(2).ToList<Client>();
        }

        /// <summary>
        /// Возвращает первых n пользователей с масимальным счетом в банке
        /// </summary>
        /// <param name="n">Число первых выводимых пользователей</param>
        public static List<Client> MaxMoneyByAccountIntoNUsers(this Bank bank, Int32 n)
        {
            Double maxMoney = bank.Accounts.Max(i => i.Balance);
            return bank.Accounts.Where(i => i.Balance == maxMoney).Select(i => i.OwnerClient).Take(n).ToList<Client>();
        }

        /// <summary>
        /// Возвращает пользователей со счетом в банке, меньше заданной величины
        /// </summary>
        /// <param name="minMoney">Минимальная сумма сравнения</param>
        public static List<Client> MinThenMoneyByAccount(this Bank bank, Double minMoney)
        {
            return bank.Accounts.Where(i => i.Balance < minMoney).Select(i => i.OwnerClient).ToList<Client>();
        }
    }
}
